public class MyBlockingQueue {
    String[] queue;
    int head,tail; //队首和队尾
    int size; //当前队列元素个数
    Object locker = new Object();

    MyBlockingQueue(int capacity) {
        queue = new String[capacity];
    }

    public void put(String str) throws InterruptedException {
        synchronized (locker) {
            if (size >= queue.length) { //注意“判断队列是否满了”这一步也要加锁（即放在 synchronized 里面）
                locker.wait();
            }
            queue[tail++] = str;
            if (tail >= queue.length) tail = 0; //也可以不用判断，直接写成 tail %= queue.length;  不过这样的效率会低一些
            size++; //不要忘了让 size++
            locker.notify();
        }
    }

    public String take() throws InterruptedException { //出队并返回该元素
        String ret = null;
        synchronized (locker) {
            if (size == 0) {
                locker.wait();
            }
            ret = queue[head];
            head++;
            if (head == queue.length) head = 0;
            size--;
            locker.notify();
        }
        return ret;
    }
}
